<template>
  <!-- 有数据时显示插槽内容 -->
  <div v-show="isEmpty(data.loading) && isEmpty(data.msg)">
    <slot></slot>
  </div>
  <!-- 加载中 -->
  <div v-show="!isEmpty(data.loading)" class="loading">
    <MyLoadingView ref="loadingView" />
    <div>{{ data.loading }}</div>
  </div>
  <!-- 无数据 -->
  <div v-show="!isEmpty(data.msg)" class="msg">
    <img src="/no_data.png" style="width: 25%;aspect-ratio: 1/1;" />
    <div>{{ isEmpty(data.msg) ? '暂无数据' : data.msg }}</div>
  </div>
</template>

<script setup lang="ts" name="MyListView">
import { isEmpty } from '@/utils/httputils';
import type { DataMyListView } from './data-view';
import { onMounted, onUnmounted, reactive, ref } from 'vue';
import MyLoadingView from './MyLoadingView.vue';
import type { CallResult, PageBean } from './data-bean';
//TS使用方法:const listView = ref<InstanceType<typeof MyListView> | null>(null)
const data = reactive<DataMyListView>({ loading: '', msg: '' })
const loadingView = ref<InstanceType<typeof MyLoadingView> | null>(null)
let delayTimer: number;
function showLoading(obj: boolean | string) {
  // log('外部调用了showLoading')
  if (obj == true) {
    //如果接口在300毫秒内反应过来了，就不用显示加载样式了
    startTimer('加载中')
  } else if (!isEmpty(obj as string)) {
    //如果接口在300毫秒内反应过来了，就不用显示加载样式了
    startTimer(obj as string)
  } else {
    clearTimeout(delayTimer)
    data.loading = ''
    loadingView.value?.stop()

  }
}
function setMessage<T>(obj: string | undefined | CallResult<T> | CallResult<PageBean<T>>) {
  showLoading('')
  if (typeof obj === 'string') {
    data.msg = obj as string
  } else if (typeof obj === 'object') {
    const result = obj as CallResult<T>;
    data.msg = result.message
    if (isEmpty(data.msg) && typeof result.data === 'object') {
      const pageBean = result.data as PageBean<T>
      if (!pageBean.list || pageBean.list.length <= 0) {
        data.msg = '暂无数据'
      }
    }
  }
}
function startTimer(info: string) {
  if (delayTimer) {
    clearTimeout(delayTimer)
  }
  delayTimer = setTimeout(() => {
    data.loading = info
    loadingView.value?.start()
  }, 200)


}

//生命周期
onMounted(() => {

})
onUnmounted(() => {

})
//外部使用: const listView = ref<InstanceType<typeof MyListView> | null>(null)，注意绑定到视图<MyView ref=child></MyView>
defineExpose({
  showLoading,
  setMessage,
})
</script>

<style lang="css" scoped>
.msg {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  justify-content: center;
  color: #7a7a7a;
  height: 100%;
}

.loading {
  background-color: #a6a6a6;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  justify-content: center;
  height: 100%;
  color: white;
  font-size: small;
}
</style>
